package com.zhuanzhuan.hero.user.util;

import com.bj58.zhuanzhuan.zzentry.common.service.entity.ServiceHeaderEntity;
import com.zhuanzhuan.hero.user.annotations.Mobile;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.reflect.MethodSignature;

import javax.validation.*;
import javax.validation.constraints.*;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @ClassName ValidUtil
 * @Description
 * @Author hanjunjun
 * @Date 2024/6/21 14:54
 */
public class ValidUtil {

    private static final Validator VALIDATOR;

    static {
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        VALIDATOR = validatorFactory.getValidator();
    }

    /**
     * 对有@Valid的方法入参进行参数校验  先校验不为null
     *
     * @param signature
     * @param args
     * @return void
     * @author  hanjunjun
     * @date 2024/6/20
     **/
    public static void preValidParams(MethodSignature signature, Object[] args) throws IllegalArgumentException{
        Parameter[] parameters = signature.getMethod().getParameters();
        if (parameters.length > 0) {
            for (int i = 0; i < parameters.length; i++) {
                Parameter parameter = parameters[i];

                NotNull notNullAnno = parameter.getAnnotation(NotNull.class);
                if (Objects.nonNull(notNullAnno) && Objects.isNull(args[i])) {
                    throw new IllegalArgumentException(notNullAnno.message());
                }

                //校验字段   需对象不能为空
                Valid validAnno = parameter.getAnnotation(Valid.class);
                if (Objects.nonNull(validAnno)) {
                    if (Objects.isNull(args[i])) {
                        throw new IllegalArgumentException("参数不可为空");
                    }
                    Set<ConstraintViolation<Object>> errorSet = VALIDATOR.validate(args[i]);
                    if (CollectionUtils.isNotEmpty(errorSet)) {
                        throw new IllegalArgumentException(errorSet.iterator().next().getMessage());
                    }

                    //有Valid注解才校验字段
//                    ValidUtil.validParamFields(args[i]);
                }
            }
        }
    }

    /**
     * 校验参数的字段
     *
     * @param argument
     * @return void
     * @author  hanjunjun
     * @date 2024/6/20
     **/
    public static void validParamFields(Object argument) {
        Class<?> clazz = argument.getClass();
        if (clazz.isPrimitive()) {
            return;
        }

        if (clazz.equals(ServiceHeaderEntity.class)) {
            return;
        }

        //是一个对象
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            Class<?> type = field.getType();
            if (type.isPrimitive()) {
                continue;
            }

            field.setAccessible(true);
            String fieldName = field.getName();
            Object fieldValue;
            try {
                fieldValue = field.get(argument);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }

            NotNull notNullAnno = field.getAnnotation(NotNull.class);
            if (Objects.nonNull(notNullAnno) && Objects.isNull(fieldValue)) {
                throw new IllegalArgumentException(notNullAnno.message());
            }

            //字符串不能为空
            NotBlank notBlankAnno = field.getAnnotation(NotBlank.class);
            if (Objects.nonNull(notBlankAnno)) {
                if (Objects.isNull(fieldValue)) {
                    throw new IllegalArgumentException(notBlankAnno.message());
                } else if (fieldValue instanceof String) {
                    if (StringUtils.isBlank((String)fieldValue)) {
                        throw new IllegalArgumentException(notBlankAnno.message());
                    }
                }
            }

            //String,List,Map不可为空
            NotEmpty notEmptyAnno = field.getAnnotation(NotEmpty.class);
            if (Objects.nonNull(notEmptyAnno)) {
                if (fieldValue instanceof String) {
                    if (StringUtils.isEmpty((String) fieldValue)) {
                        throw new IllegalArgumentException(notEmptyAnno.message());
                    }
                } else if (fieldValue instanceof Collection) {
                    if (CollectionUtils.isEmpty((Collection) fieldValue)) {
                        throw new IllegalArgumentException(notEmptyAnno.message());
                    }
                } else if (fieldValue instanceof Map) {
                    if (MapUtils.isEmpty((Map) fieldValue)) {
                        throw new IllegalArgumentException(notEmptyAnno.message());
                    }
                }
            }

            //手机号格式校验   可以为空
            Mobile mobileAnno = field.getAnnotation(Mobile.class);
            if (Objects.nonNull(mobileAnno)) {
                if (Objects.nonNull(fieldValue)) {
                    if (!(fieldValue instanceof String)) {
                        throw new IllegalArgumentException("手机号格式错误");
                    }
                    String strValue = (String)fieldValue;
                    if (StringUtils.isNotBlank(strValue) && !strValue.matches("^1[3-9]\\d{9}$")) {
                        throw new IllegalArgumentException(mobileAnno.message());
                    }
                }
            }

            //String正则校验
            Pattern patternAnno = field.getAnnotation(Pattern.class);
            if (Objects.nonNull(patternAnno)) {
                if (!(fieldValue instanceof String)) {
                    throw new IllegalArgumentException("Pattern注解字段类型异常");
                }
                String strValue = (String)fieldValue;
                if (StringUtils.isBlank(strValue) || !strValue.matches(patternAnno.regexp())) {
                    throw new IllegalArgumentException(patternAnno.message());
                }
            }

            //String、List、Map的size最大最小值  可以为空
            Size sizeAnno = field.getAnnotation(Size.class);
            if (Objects.nonNull(sizeAnno)) {
                int min = sizeAnno.min();
                int max = sizeAnno.max();
                int valueSize;

                if (Objects.nonNull(fieldValue)) {
                    if (fieldValue instanceof String) {
                        valueSize = ((String)fieldValue).length();
                    } else if (fieldValue instanceof Collection) {
                        Collection collectionValue = (Collection)fieldValue;
                        valueSize = collectionValue.size();
                    } else if (fieldValue instanceof Map) {
                        Map mapValue = (Map)fieldValue;
                        valueSize = mapValue.size();
                    } else {
                        throw new IllegalArgumentException("size注解字段类型错误");
                    }
                    if (valueSize < min || valueSize > max) {
                        throw new IllegalArgumentException(sizeAnno.message());
                    }
                }
            }
        }
    }
}
